-module(edrp_listener).

-behaviour(gen_server).

-export([start_link/2]).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

-include("edrp_acceptors.hrl").

-record(state, {sock, 
                startup, 
                shutdown,
                current,
                spare,
                spareList,
                createSpeed,
                acceptors}).

%%--------------------------------------------------------------------

start_link(Startup, Shutdown) ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, {Startup, Shutdown}, []).

%%--------------------------------------------------------------------

init({Startup, Shutdown}) ->
    process_flag(trap_exit, true),

    {ok, Ip, Port} = edrp_misc:read_listen_addr(),
    {ok, Acceptors} = edrp_misc:read_acceptors(),
    %% limit, start, minispare, maxspare, maxreq
    case gen_tcp:listen(Port, [binary, {packet, raw},{ip, Ip}, 
                               {active, false}, {reuseaddr, true}]) of
        {ok, LSock} ->
            lists:foreach(
                fun (_) ->
                    {ok, _Pid} = supervisor:start_child(edrp_acceptor_sup,
                                    [LSock, Acceptors#acceptors.maxreq])
                end,
                lists:duplicate(Acceptors#acceptors.limit, dummy)),
            {ok, {LIPAddress, LPort}} = inet:sockname(LSock),
            error_logger:info_msg("started edrp_proxy on ~s:~p~n",
                                  [inet_parse:ntoa(LIPAddress), LPort]),
            %% apply(M, F, A ++ [IPAddress, Port]),
            {ok, #state{sock=LSock, startup=Startup, shutdown=Shutdown}};
        {error, Reason} ->
            error_logger:error_msg(
              "failed to start edrp_proxy on ~s:~p - ~p~n",
              [inet_parse:ntoa(Ip), Port, Reason]),
            {stop, {cannot_listen, Ip, Port, Reason}}
    end.

handle_call(_Request, _From, State) ->
    {noreply, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, #state{sock=LSock}) ->
    {ok, {IPAddress, Port}} = inet:sockname(LSock),
    %%apply(M, F, A ++ [IPAddress, Port]),
    gen_tcp:close(LSock),
    error_logger:info_msg("stopped edrp_proxy on ~s:~p~n",
                          [inet_parse:ntoa(IPAddress), Port]).

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.
